// autoupdate.js
// 定义模块的自动更新逻辑
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const extract = require('extract-zip');

const UPDATE_CONFIG = {
    models_cloud: {
        base_url: 'https://label-anything.bd.bcebos.com/labelapp/models_cloud/',
        version_url: 'https://label-anything.bd.bcebos.com/labelapp/models_cloud/VERSION',
        pack_url: 'https://label-anything.bd.bcebos.com/labelapp/models_cloud/models-$VERSION.zip',
        install_dir: '$HOME/models_cloud/',
        install_version_path: '$HOME/models_cloud/VERSION'
    },
    datasets_cloud: {
        base_url: 'https://label-anything.bd.bcebos.com/labelapp/datasets_cloud/',
        version_url: 'https://label-anything.bd.bcebos.com/labelapp/datasets_cloud/VERSION',
        pack_url: 'https://label-anything.bd.bcebos.com/labelapp/datasets_cloud/datasets-$VERSION.zip',
        install_dir: '$HOME/datasets_cloud/',
        install_version_path: '$HOME/datasets_cloud/VERSION'
    }
};

class AutoUpdater {
    constructor(app) {
        this.app = app;
        this.userDataPath = app.userDataPath;
    }

    async update(module) {
        try {
            this.module = module;
            this.base_url = UPDATE_CONFIG[module].base_url;
            this.version_url = UPDATE_CONFIG[module].version_url;
            this.install_dir = UPDATE_CONFIG[module].install_dir.replace('$HOME', this.userDataPath);
            this.install_version_path = UPDATE_CONFIG[module].install_version_path.replace('$HOME', this.userDataPath);
            this.pack_url = UPDATE_CONFIG[module].pack_url;
            this.new_version = null;
            this.install_version = null;

            if (await this.checkUpdate()) {
                console.log(`## New version available for module [${this.module}]!`);
                console.log(`## new_version = ${this.new_version}, install_version = ${this.install_version}`);

                // 删除模块所在目录并创建空目录
                if (fs.existsSync(this.install_dir)) {
                    this.deleteFolderRecursive(this.install_dir);
                }
                fs.mkdirSync(this.install_dir);

                // 下载、解压并安装新版本
                await this.installNewVersion();
            } else {
                console.log(`## No need to update module [${this.module}]!`);
                console.log(`## new_version = ${this.new_version}, install_version = ${this.install_version}`);
            }
        } catch (error) {
            console.error('## Error updating:', error);
        }
    }

    async checkUpdate() {
        try {
            const response = await axios.get(this.version_url);
            this.new_version = response.data;

            if (fs.existsSync(this.install_version_path)) {
                this.install_version = fs.readFileSync(this.install_version_path, 'utf8');
            }

            return this.new_version !== this.install_version;
        } catch (error) {
            console.error('Error checking update:', error.status);
            return false;
        }
    }

    // 递归删除目录
    deleteFolderRecursive(path) {
        if (fs.existsSync(path)) {
            fs.readdirSync(path).forEach((file) => {
                const curPath = path + '/' + file;
                if (fs.lstatSync(curPath).isDirectory()) {
                    this.deleteFolderRecursive(curPath);
                } else {
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }

    async installNewVersion() {
        const zipPath = path.join(this.install_dir, 'update.zip');
        const downloadUrl = this.pack_url.replace('$VERSION', this.new_version);

        try {
            const { data, headers } = await axios.get(downloadUrl, { responseType: 'stream' });
            const totalLength = headers['content-length'];

            console.log(`## Starting download: ${downloadUrl}`);
            let downloadedLength = 0;

            const writer = fs.createWriteStream(zipPath);
            data.on('data', (chunk) => {
                downloadedLength += chunk.length;
                const percent = ((downloadedLength / totalLength) * 100).toFixed(2);
                process.stdout.write(`## Downloaded: ${percent}%\r`);
            });

            data.pipe(writer);

            await new Promise((resolve, reject) => {
                writer.on('finish', resolve);
                writer.on('error', reject);
            });

            console.log('\n## Download complete.');

            // 解压并安装新版本
            await extract(zipPath, { dir: this.install_dir });
            fs.writeFileSync(this.install_version_path, this.new_version, 'utf8');
            console.log(`## Updated [${this.module}] to version ${this.new_version}`);

            // 删除下载的zip文件
            fs.unlinkSync(zipPath);
        } catch (error) {
            console.error('## Error installing new version:', error);
        }
    }
}

module.exports = { AutoUpdater };
